package ar.edu.itba.pod.legajo45002;

import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

import ar.edu.itba.event.EventInformation;
import ar.edu.itba.event.RemoteEventDispatcher;
import ar.edu.itba.node.Node;
import ar.edu.itba.node.NodeInformation;
import ar.edu.itba.pod.agent.runner.Agent;

public class RemoteEventDispatcherImpl extends UnicastRemoteObject implements RemoteEventDispatcher {
	
	private BlockingQueue<EventInformation> pendingEventsQueue;
	private BlockingQueue<EventInformation> alreadyProcessedEventsQueue;

	public RemoteEventDispatcherImpl() throws RemoteException{
		pendingEventsQueue = new LinkedBlockingDeque<EventInformation>();
		alreadyProcessedEventsQueue = new LinkedBlockingDeque<EventInformation>();
		Registry reg = DistributedNodeImpl.getRegistry();
		try {
			reg.bind(Node.DISTRIBUTED_EVENT_DISPATCHER, this);
		} catch (AccessException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (AlreadyBoundException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public boolean publish(EventInformation event) throws RemoteException,	InterruptedException {
		if( !pendingEventsQueue.contains(event) && !alreadyProcessedEventsQueue.contains(event) ){
			pendingEventsQueue.add(event);
			return true;
	//		System.out.println("adding event : " + event.event());
		}
		return false;
	}

	@Override
	public Set<EventInformation> newEventsFor(NodeInformation nodeInformation)throws RemoteException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BlockingQueue<Object> moveQueueFor(Agent agent)
			throws RemoteException {
		// TODO Auto-generated method stub
		return null;
	}
	
	public EventInformation getEventFromPending(){
	//	System.out.println("polling event" + pendingEventsQueue.poll().event() );
		return pendingEventsQueue.poll();

	}
	
	public BlockingQueue<EventInformation> getPendingEventsQueue() {
		return pendingEventsQueue;
	}
	
	public BlockingQueue<EventInformation> getAlreadyProcessedEventsQueue() {
		return alreadyProcessedEventsQueue;
	}

	public void addProcessedEvent(EventInformation event) {

		alreadyProcessedEventsQueue.add(event);
	//	System.out.println("putting processed event" + event.event());

	}

}
